package com.fablesoft.projectdatacollect.http;

import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.authentication.utils.ToastUtil;
import com.fablesoft.projectdatacollect.MyApplication;
import com.fablesoft.projectdatacollect.bean.BaseResponse;
import com.fablesoft.projectdatacollect.util.CommonUtils;
import com.fablesoft.projectdatacollect.util.Config;
import com.fablesoft.projectdatacollect.util.JyCustomDialog;
import com.fablesoft.projectdatacollect.util.Log4jUtil;
import com.fablesoft.projectdatacollect.util.LogUtil;

import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 */
public final class HttpUploadFilesThread extends Thread {
	/**
	 * 日志标签
	 */
	private static final String TAG = "HttpUploadFilesThread";

	/**
	 * 用户控制是否中断请求的标志
	 */
	private boolean cancel = false;

	/**
	 * 请求url
	 */
	private String url;

	/**
	 * POST请求数据
	 *
	 */
	private Map<String, Object> parms;

	/**
	 * POST请求数据
	 *
	 */
	private List<File> files;
    private List<String> filenames;

	private byte[] file;

	/**
	 * HTTP请求监听的实现类，当请求有结果时会设置该类的相应方法
	 */
	private HttpListener listener;

	private Class clazz;

    public HttpUploadFilesThread(String url, HttpListener listener,byte[] file,
                                 Map<String, Object> parms, Class clazz) {
        this.url = url;
        this.parms = parms;
        this.listener = listener;
        this.file = file;
        this.clazz = clazz;
    }

    public HttpUploadFilesThread(String url, HttpListener listener, List<File> files, List<String> filenames,
                            Map<String, Object> parms, Class clazz) {
        this.url = url;
        this.parms = parms;
        this.listener = listener;
        this.files = files;
        this.filenames = filenames;
        this.clazz = clazz;
    }

    public HttpUploadFilesThread(String url, HttpListener listener, Map<String, Object> parms, Class clazz) {
        this.url = url;
        this.parms = parms;
        this.listener = listener;
        this.clazz = clazz;
    }

	/**
	 * 发送HTTP请求，并将结果设置回HttpListener的实现类中
	 * 
	 */
	@Override
	public void run() {
		String result = null;
		result = sendRequest();

		// 如果用户还没有中断请求
		if (!cancel) {
			try {
				BaseResponse response = JsonUtil.getResponse(result, clazz);
				if(response != null && "403".equals(response.getCode())){
					listener.onNotLogin(response);
				}else{
					listener.onRequestFinish(response);
				}
			} catch (Exception e) {
                Log4jUtil.e(e.toString());
				e.printStackTrace();
			}
		}
	}

	/**
	 * 发送请求获取响应
	 * 
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	private String sendRequest() {
        Log.d("http",parms.toString());
		URL myURL = null;
		HttpURLConnection conn = null;
		InputStream is = null;
//		FileInputStream fis = null;
		BufferedInputStream in = null;
		DataOutputStream dos = null;
		StringBuffer response = new StringBuffer();
		String prefix = "--";
		String boundary = "*****";
		String end = "\r\n";
		try {
			Log.d("sglei-upload", "upload url = " + url);
			Log4jUtil.d(url);
			myURL = new URL(url);
			conn = (HttpURLConnection) myURL.openConnection();
            /* 允许Input、Output，不使用Cache */
			conn.setDoInput(true);
			conn.setChunkedStreamingMode(4096);
			conn.setDoOutput(true);
			conn.setUseCaches(false);
			/* 设置传送的method=POST */
			conn.setRequestMethod("POST");
			/* setRequestProperty */
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("Charset", "UTF-8");
			conn.setRequestProperty("Content-Type",
					"multipart/form-data;charset=UTF-8;boundary=" + boundary);
            conn.setRequestProperty(Config.CLIENT_TYPE_KEY, Config.CLIENT_TYPE_VALUE);
			LogUtil.i("lzx", "cookie:" + MyApplication.getInstance().getSessionId());
			if(!TextUtils.isEmpty(MyApplication.getInstance().getSessionId())){
				conn.setRequestProperty("Cookie", MyApplication.getInstance().getSessionId());
			}
			/* 设置DataOutputStream */
			dos = new DataOutputStream(conn.getOutputStream());
			if(parms != null){
				for(Entry<String, Object> entry : parms.entrySet()){
					if(entry.getValue() != null && !TextUtils.isEmpty(entry.getValue().toString())){
						StringBuffer buf = new StringBuffer();
						buf.append(prefix + boundary  + end);
						buf.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + end);
						buf.append(end);
						buf.append(entry.getValue().toString());
						buf.append(end);
						dos.write(buf.toString().getBytes("UTF-8"));
					}
				}
			}
			if((files == null || files.size() == 0) && file == null){
				Log.e(TAG,"files is null  or size is 0");
				return null;
			}else{
				if(files != null){
                    Log.d("sglei-upload", "size = " + files.size());
					for(int i=0; i<files.size(); i++){
						dos.writeBytes(prefix + boundary + end);
						dos.writeBytes("Content-Disposition: form-data; "
								+ "name=\"file\";filename=\""+ filenames.get(i) + end);
						dos.writeBytes("Content-Type: application/octet-stream" + end);  
						dos.writeBytes(end);
						/* 取得文件的FileInputStream */
						in = new  BufferedInputStream(new FileInputStream(files.get(i))) ;
//						fis = new FileInputStream(files.get(i));
						/* 设置每次写入1024bytes */
						int bufferSize = 4096;
						byte[] buffer = new byte[bufferSize];
						int length = -1;
						/* 从文件读取数据至缓冲区 */
						while ((length = in.read(buffer)) != -1) {
							/* 将资料写入DataOutputStream中 */
							dos.write(buffer, 0, length);
							Log.i("lzx", "write file");
						}
						dos.writeBytes(end);
						Log.i("lzx", "write end");
						in.close();
						in = null;
					}
				}else if(file != null){
					dos.writeBytes(prefix + boundary + end);
					dos.writeBytes("Content-Disposition: form-data; "
							+ "name=\"file\";filename=\"file.jpg\"" + end);
					dos.writeBytes("Content-Type: application/octet-stream" + end);  
					dos.writeBytes(end);
					dos.write(file, 0, file.length);
					dos.writeBytes(end);
				}
			}
			dos.writeBytes(prefix + boundary + prefix + end);  
			dos.writeBytes(end); 
	        dos.flush();
            Log.d("sglei-upload", "upload response code = " + conn.getResponseCode());
			/* 取得Response内容 */
	        if (conn.getResponseCode() == 200) {
				is = new BufferedInputStream(conn.getInputStream());
				byte[] buf = new byte[2048];
				is = conn.getInputStream();
				for (int n; (n = is.read(buf)) != -1;) {
					response.append(new String(buf, 0, n, "UTF-8"));
				}
//                Log.d("sglei-upload", "upload response = " + response.toString());
				CommonUtils.showLogCompletion(response.toString(), 1024 * 2);
				Log4jUtil.d(response.toString());
			} else {
				Log4jUtil.d(conn.getResponseCode() + "");
			}
		} catch (Exception e) {
            Log4jUtil.e(e.toString());
			response = null;
		} finally {
			if(in != null){
				try {
					in.close();
				} catch (IOException e) {
                    Log4jUtil.e(e.toString());
					Log.e(TAG, "close outputStream " + e.toString());
				}
			}
			if (dos != null) {
				try {
					dos.close();
				} catch (IOException e) {
                    Log4jUtil.e(e.toString());
					Log.e(TAG, "close outputStream " + e.toString());
				}
			}
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
                    Log4jUtil.e(e.toString());
					Log.e(TAG, "close inputstream " + e.toString());
				}
			}
			if (conn != null) {
				conn.disconnect();
			}
		}
		return response == null ? null : response.toString();
	}

}
